package vn.codespot.hms.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.text.TextUtils;

public class JSonUtils {
    /**
     * Get list of string values. JSON object will be something like this: {"arrName": ["value1", "value2", "value3"]}
     * 
     * @param arrName
     * @param jsonObj
     * @return
     */
    public static List<String> getListStringValue(String arrName, JSONObject jsonObj) {
        List<String> ret = null;
        if (!TextUtils.isEmpty(arrName) && jsonObj != null) {
            try {
                Object obj = jsonObj.get(arrName);
                if (obj instanceof JSONArray) {
                    ret = new ArrayList<String>();
                    JSONArray arr = (JSONArray) obj;
                    for (int i = 0; i < arr.length(); i++) {
                        try {
                            String value = (String) arr.get(i);
                            ret.add(value);
                        } catch (ClassCastException e) {
                            continue;
                        }

                    }
                }
            } catch (JSONException e) {
                LogUtil.e("JSONException: ", e);
            }
        }
        return ret;
    }

    /**
     * Create new JSON instance with given string
     * 
     * @param json
     * @return
     */
    public static JSONObject getRootJSonObject(String json) {
        try {
            return new JSONObject(json);
        } catch (JSONException e) {
            LogUtil.e("JSONException: ", e);
            return null;
        }
    }

    public static String getJSonAsString(JSONObject jsonObj) {
        String ret = null;
        if (jsonObj != null) {
            ret = jsonObj.toString();
        }
        return ret;
    }

    /**
     * Get JSON object as in string format with given collection of name and string value pairs.
     * 
     * @param data
     *            name and string value pairs
     * @return JSON string format like: {"name1": "value1", "name2": "value2"}
     */
    public static String getJSonAsString(Map<String, String> data) {
        JSONObject jsonObj = getJSonObject(data);
        return getJSonAsString(jsonObj);
    }

    /**
     * Get JSON object with given collection of name and string value pairs.
     * 
     * @param data
     *            a collection of name and string value pairs
     * @return JSON object which indicates string format like: {"name1": "value1", "name2": "value2"}
     */
    public static JSONObject getJSonObject(Map<String, String> data) {
        if (data == null || data.isEmpty()) {
            return null;
        } else {
            JSONObject jsonObj = new JSONObject();
            for (Entry<String, String> entry : data.entrySet()) {
                String name = entry.getKey();
                String value = entry.getValue();
                if (!TextUtils.isEmpty(name) && value != null) {
                    try {
                        // jsonObj.accumulate(name, value);
                        jsonObj.put(name, value);
                    } catch (JSONException e) {
                        LogUtil.e("JSONException: ", e);
                        return null;
                    }
                }
            }
            return jsonObj;
        }
    }

    /**
     * Add JSON array object into given JSON object with arrName
     * 
     * @param root
     * @param arrName
     * @param jsonArr
     */
    public static void addJSonArary(JSONObject root, String arrName, JSONArray jsonArr) {
        try {
            if (jsonArr != null && jsonArr.length() != 0) {
                root.accumulate(arrName, jsonArr);
            }
        } catch (JSONException e) {
            LogUtil.e("JSONException: ", e);
        }
    }

    /**
     * Get JSON array object with given lstData. Each element within lstData contains the collection of name and string value pairs which
     * represented for each JSON object in array
     * 
     * @param lstData
     * @return
     */
    public static JSONArray getJsonArray(List<Map<String, String>> lstData) {
        JSONArray arr = null;
        if (lstData != null && !lstData.isEmpty()) {
            arr = new JSONArray();
            for (Map<String, String> data : lstData) {
                JSONObject jsonObj = getJSonObject(data);
                arr.put(jsonObj);
            }
        }
        return arr;
    }

    /**
     * Get collection of name and string value pairs with given set of attribute names
     * 
     * @param attrNames
     * @param jsonObj
     * @return
     */
    public static Map<String, String> getSingleAttributeValuePairs(Collection<String> attrNames, JSONObject jsonObj) {
        Map<String, String> ret = null;
        if ((attrNames != null && !attrNames.isEmpty()) && jsonObj != null) {
            ret = new HashMap<String, String>();
            for (String name : attrNames) {
                try {
                    ret.put(name, jsonObj.getString(name));
                } catch (JSONException e) {
                    continue;
                }
            }
        }
        return ret;
    }

    /**
     * Get the list of a collection of name and string value pairs. Each collection inside the list should contain a set of attribute names
     * 
     * @param arrName
     * @param attrNames
     * @param jsonObj
     * @return
     */
    public static List<Map<String, String>> getSingleAttributeValuePairsArray(String arrName, Collection<String> attrNames,
            JSONObject jsonObj) {
        List<Map<String, String>> arr = null;
        if (!TextUtils.isEmpty(arrName) && jsonObj != null && !jsonObj.isNull(arrName) && attrNames != null && !attrNames.isEmpty()) {
            try {
                arr = new ArrayList<Map<String, String>>();
                JSONArray jsonArr = jsonObj.getJSONArray(arrName);
                for (int i = 0; i < jsonArr.length(); i++) {
                    JSONObject obj = jsonArr.getJSONObject(i);
                    arr.add(getSingleAttributeValuePairs(attrNames, obj));
                }
            } catch (JSONException e) {
                LogUtil.e("JSONException: ", e);
            }
        }
        return arr;
    }
}
